////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//                                                                                                                            //
//                                                         WNProject                                                          //
//                                                                                                                            //
//            This file is distributed under the BSD 2-Clause open source license. See License.txt for details.               //
//                                                                                                                            //
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#ifndef __WN_POINT_2_H__
#define __WN_POINT_2_H__

#include "WNCore/inc/WNBase.h"
#include "WNMath/inc/WNSnapDirection.h"

namespace WNMath {
    class WNPoint3;
    class WNVector2;
    class WNVector3;
    class WNVector4;

    class WNPoint2 {
    public:
        WNPoint2();
        explicit WNPoint2(const WN_FLOAT32* _f);
        explicit WNPoint2(WN_FLOAT32 _x, WN_FLOAT32 _y);

        operator WN_FLOAT32* ();
        operator const WN_FLOAT32* () const;

        WN_FLOAT32& operator () (WN_INT32 _index);
        WN_FLOAT32 operator () (WN_INT32 _index) const;

        WNPoint2 operator + () const;
        WNPoint2 operator - () const;

        WNPoint2 operator += (const WNVector2& _vector);
        WNPoint2 operator -= (const WNVector2& _vector);

        WNPoint2 operator + (const WNVector2& _vector) const;
        WNPoint2 operator - (const WNVector2& _vector) const;

        WNVector2 operator - (const WNPoint2& _point) const;
        WNVector2 operator * (const WNPoint2& _point) const;

        WN_BOOL  operator == (const WNPoint2& _point) const;
        WN_BOOL  operator != (const WNPoint2& _point) const;

        WN_VOID Zero();
        WN_VOID Snap(WNSnapDirection _direction = WN_SNAP_NEAREST);
        WN_VOID Translate(WN_FLOAT32 _translation);
        WN_VOID Translate(WN_FLOAT32 _x, WN_FLOAT32 _y);
        WN_VOID Translate(const WNVector2& _translation);

        WN_BOOL IsZero() const;

        WN_VOID Set(const WN_FLOAT32* _f);
        WN_VOID Set(WN_FLOAT32 _x, WN_FLOAT32 _y);

        WNPoint2 GetSnaped(WNSnapDirection _direction = WN_SNAP_NEAREST) const;
        WNPoint2 GetTranslated(WN_FLOAT32 _translation) const;
        WNPoint2 GetTranslated(WN_FLOAT32 _x, WN_FLOAT32 _y) const;
        WNPoint2 GetTranslated(const WNVector2& _translation) const;

        WNPoint3 ToPoint3() const;
        WNVector2 ToVector2() const;
        WNVector3 ToVector3() const;
        WNVector4 ToVector4() const;

    public:
        union {
            struct {
                WN_FLOAT32 x;
                WN_FLOAT32 y;
            };

            WN_FLOAT32 raw[2];
        };
    };
}

#endif // __WN_POINT_2_H__